import { z } from "zod";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
import type { CoursePageParams } from "~/types/route";
import { generateRandomCode } from "~/utils/generateCode";

const courseSchema = z.object({
  title: z.string().min(1, "课程名称不能为空"),
  description: z.string().optional(),
  objectives: z.string().optional(),
  prerequisites: z.string().optional(),
  status: z.enum(["DRAFT", "PUBLISHED"]).default("DRAFT"),
});

export const coursesRouter = createTRPCRouter({
  // 获取课程列表
  list: protectedProcedure
    .input(
      z.object({
        page: z.number().min(1).default(1),
        pageSize: z.number().min(1).default(10),
        status: z.enum(["DRAFT", "PUBLISHED", "ALL"]).optional(),
      }).optional().default({
        page: 1,
        pageSize: 10,
      })
    )
    .query(async ({ ctx, input }) => {
      try {
        const { page, pageSize, status } = input;
        const where = {
          ...(ctx.session.user.role === "TEACHER"
            ? { teacherId: ctx.session.user.id }
            : {}),
          ...(status && status !== "ALL" ? { status } : {}),
        };

        const [total, items] = await Promise.all([
          ctx.db.course.count({ where }),
          ctx.db.course.findMany({
            where,
            skip: (page - 1) * pageSize,
            take: pageSize,
            include: {
              teacher: {
                select: {
                  id: true,
                  name: true,
                },
              },
            },
            orderBy: {
              createdAt: "desc",
            },
          }),
        ]);

        return {
          items,
          total,
          page,
          pageSize,
          totalPages: Math.ceil(total / pageSize),
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: "获取课程列表失败",
          cause: error,
        });
      }
    }),

  // 创建课程
  create: protectedProcedure
    .input(courseSchema)
    .mutation(async ({ ctx, input }) => {
      try {
        if (ctx.session.user.role !== "TEACHER") {
          throw new TRPCError({
            code: "FORBIDDEN",
            message: "只有教师可以创建课程",
          });
        }

        return await ctx.db.course.create({
          data: {
            ...input,
            teacherId: ctx.session.user.id,
          },
        });
      } catch (error) {
        if (error instanceof TRPCError) throw error;
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: "创建课程失败",
          cause: error,
        });
      }
    }),

  // 更新课程
  update: protectedProcedure
    .input(
      z.object({
        courseId: z.string(),
        data: courseSchema.partial(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      try {
        const course = await ctx.db.course.findUnique({
          where: { id: input.courseId },
        });

        if (!course) {
          throw new TRPCError({
            code: "NOT_FOUND",
            message: "课程不存在",
          });
        }

        if (
          course.teacherId !== ctx.session.user.id &&
          ctx.session.user.role !== "ADMIN"
        ) {
          throw new TRPCError({
            code: "FORBIDDEN",
            message: "没有权限修改此课程",
          });
        }

        return await ctx.db.course.update({
          where: { id: input.courseId },
          data: input.data,
        });
      } catch (error) {
        if (error instanceof TRPCError) throw error;
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: "更新课程失败",
          cause: error,
        });
      }
    }),

  // 删除课程
  delete: protectedProcedure
    .input(z.string())
    .mutation(async ({ ctx, input: courseId }) => {
      try {
        const course = await ctx.db.course.findUnique({
          where: { id: courseId },
        });

        if (!course) {
          throw new TRPCError({
            code: "NOT_FOUND",
            message: "课程不存在",
          });
        }

        if (
          course.teacherId !== ctx.session.user.id &&
          ctx.session.user.role !== "ADMIN"
        ) {
          throw new TRPCError({
            code: "FORBIDDEN",
            message: "没有权限删除此课程",
          });
        }

        return await ctx.db.course.delete({
          where: { id: courseId },
        });
      } catch (error) {
        if (error instanceof TRPCError) throw error;
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: "删除课程失败",
          cause: error,
        });
      }
    }),

  // 获取课程详情
  getById: protectedProcedure
    .input(z.object({
      courseId: z.string(),
    }))
    .query(async ({ ctx, input }) => {
      try {
        const course = await ctx.db.course.findUnique({
          where: { id: input.courseId },
          include: {
            teacher: {
              select: {
                id: true,
                name: true,
              },
            },
            tasks: {
              include: {
                steps: true,
              },
              orderBy: {
                orderIndex: 'asc',
              },
            },
          },
        });

        if (!course) {
          throw new TRPCError({
            code: "NOT_FOUND",
            message: "课程不存在",
          });
        }

        return course;
      } catch (error) {
        if (error instanceof TRPCError) throw error;
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: "获取课程详情失败",
          cause: error,
        });
      }
    }),

  getTasks: protectedProcedure
    .input(z.object({ courseId: z.string() }))
    .query(async ({ ctx, input }) => {
      return await ctx.db.task.findMany({
        where: { courseId: input.courseId },
        include: { 
          steps: {
            include: {
              completions: {
                where: {
                  userId: ctx.session.user.id
                }
              }
            },
            orderBy: {
              orderIndex: 'asc'
            }
          }
        },
        orderBy: { orderIndex: 'asc' }
      });
    }),
    
  getTaskContent: publicProcedure
    .input(z.object({ 
      courseId: z.string(),
      taskId: z.string().optional(),
      stepId: z.string().optional()
    }))
    .query(async ({ ctx, input }) => {
      if (!input.taskId && !input.stepId) return null;
      
      if (input.stepId) {
        return await ctx.db.step.findFirst({
          where: { 
            id: input.stepId,
            task: {
              courseId: input.courseId
            }
          },
          select: {
            id: true,
            title: true,
            description: true
          }
        });
      }
      
      return await ctx.db.task.findFirst({
        where: { 
          id: input.taskId!,
          courseId: input.courseId
        },
        select: {
          id: true,
          title: true,
          content: true
        }
      });
    }),

  getAllSteps: protectedProcedure
    .input(z.object({
      courseId: z.string()
    }))
    .query(async ({ ctx, input }) => {
      return await ctx.db.step.findMany({
        where: {
          task: {
            courseId: input.courseId
          }
        },
        select: {
          id: true,
          title: true,
          description: true,
          taskId: true,
          orderIndex: true,
          status: true,
          completions: {
            where: {
              userId: ctx.session.user.id
            }
          }
        },
        orderBy: {
          orderIndex: 'asc'
        }
      });
    }),

  // 获取学生的课程注册信息和进度
  getEnrollment: protectedProcedure
    .input(z.object({
      courseId: z.string()
    }))
    .query(async ({ ctx, input }) => {
      const enrollment = await ctx.db.enrollment.findFirst({
        where: {
          courseId: input.courseId,
          studentId: ctx.session.user.id
        }
      });

      if (!enrollment) {
        // 如果没有注册记录，创建一个新的
        return await ctx.db.enrollment.create({
          data: {
            courseId: input.courseId,
            studentId: ctx.session.user.id,
            status: "ENROLLED",
            progress: 0
          }
        });
      }

      return enrollment;
    }),

  // 生成课程邀请链接
  generateInviteLink: protectedProcedure
    .input(z.object({
      courseId: z.string(),
    }))
    .mutation(async ({ ctx, input }) => {
      try {
        const course = await ctx.db.course.findUnique({
          where: { id: input.courseId },
          include: { teacher: true },
        });

        if (!course) {
          throw new TRPCError({
            code: "NOT_FOUND",
            message: "课程不存在",
          });
        }

        if (course.teacherId !== ctx.session.user.id) {
          throw new TRPCError({
            code: "FORBIDDEN",
            message: "只有课程教师可以生成邀请链接",
          });
        }

        // 生成邀请记录
        const invitation = await ctx.db.courseInvitation.create({
          data: {
            courseId: input.courseId,
            inviterId: ctx.session.user.id,
            expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7天后过期
            code: generateRandomCode(12),
          },
        });

        return invitation;
      } catch (error) {
        if (error instanceof TRPCError) throw error;
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: "生成邀请链接失败",
          cause: error,
        });
      }
    }),

  // 获取邀请信息
  getInvitation: publicProcedure
    .input(z.object({
      invitationId: z.string(),
    }))
    .query(async ({ ctx, input }) => {
      try {
        const invitation = await ctx.db.courseInvitation.findUnique({
          where: { id: input.invitationId },
          include: {
            course: {
              include: {
                teacher: {
                  select: {
                    id: true,
                    name: true,
                  },
                },
              },
            },
          },
        });

        if (!invitation) {
          throw new TRPCError({
            code: "NOT_FOUND",
            message: "邀请链接不存在或已失效",
          });
        }

        return invitation;
      } catch (error) {
        if (error instanceof TRPCError) throw error;
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: "获取邀请信息失败",
          cause: error,
        });
      }
    }),

  // 通过邀请链接加入课程
  joinCourse: protectedProcedure
    .input(z.object({
      invitationId: z.string(),
    }))
    .mutation(async ({ ctx, input }) => {
      try {
        const invitation = await ctx.db.courseInvitation.findUnique({
          where: { id: input.invitationId },
          include: { course: true },
        });

        if (!invitation) {
          throw new TRPCError({
            code: "NOT_FOUND",
            message: "邀请链接不存在或已失效",
          });
        }

        if (invitation.expiresAt < new Date()) {
          throw new TRPCError({
            code: "BAD_REQUEST",
            message: "邀请链接已过期",
          });
        }

        // 检查是否已经加入过该课程
        const existingEnrollment = await ctx.db.enrollment.findUnique({
          where: {
            courseId_studentId: {
              courseId: invitation.courseId,
              studentId: ctx.session.user.id,
            },
          },
        });

        if (existingEnrollment) {
          throw new TRPCError({
            code: "BAD_REQUEST",
            message: "您已经加入过这个课程了",
          });
        }

        // 创建课程报名记录
        const enrollment = await ctx.db.enrollment.create({
          data: {
            courseId: invitation.courseId,
            studentId: ctx.session.user.id,
            userId: ctx.session.user.id,
            status: "ENROLLED",
          },
          include: {
            course: true,
          },
        });

        // 为学生创建所有任务的进度记录
        const tasks = await ctx.db.task.findMany({
          where: { courseId: invitation.courseId },
        });

        await ctx.db.taskProgress.createMany({
          data: tasks.map(task => ({
            taskId: task.id,
            enrollmentId: enrollment.id,
            status: "NOT_STARTED",
          })),
        });

        return enrollment;
      } catch (error) {
        if (error instanceof TRPCError) throw error;
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: "加入课程失败",
          cause: error,
        });
      }
    }),

  // 获取我加入的课程列表
  listEnrolled: protectedProcedure
    .input(
      z.object({
        page: z.number().min(1).default(1),
        pageSize: z.number().min(1).default(10),
        status: z.enum(["ENROLLED", "COMPLETED", "DROPPED", "ALL"]).optional(),
      }).optional().default({
        page: 1,
        pageSize: 10,
      })
    )
    .query(async ({ ctx, input }) => {
      try {
        const { page, pageSize, status } = input;
        const where = {
          studentId: ctx.session.user.id,
          ...(status && status !== "ALL" ? { status } : {}),
        };

        const [total, items] = await Promise.all([
          ctx.db.enrollment.count({ where }),
          ctx.db.enrollment.findMany({
            where,
            skip: (page - 1) * pageSize,
            take: pageSize,
            include: {
              course: {
                include: {
                  teacher: {
                    select: {
                      id: true,
                      name: true,
                    },
                  },
                },
              },
              taskProgress: true,
            },
            orderBy: {
              enrolledAt: "desc",
            },
          }),
        ]);

        return {
          items,
          total,
          page,
          pageSize,
          totalPages: Math.ceil(total / pageSize),
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: "获取已加入的课程列表失败",
          cause: error,
        });
      }
    }),
}); 